import { AgentMCPBridge, AgentConfig } from '../core/agent-mcp-bridge';

// 演示不同AI模型返回格式的处理
export class AIAgentResponseHandler {
  
  // 情况1：结构化返回（如OpenAI GPT-4+）
  handleStructuredResponse(response: any): { content: string; toolCalls?: any[] } {
    // OpenAI格式
    if (response.choices && response.choices[0]?.message?.tool_calls) {
      return {
        content: response.choices[0].message.content || "",
        tool_calls: response.choices[0].message.tool_calls
      };
    }
    
    // Claude 3格式
    if (response.content && Array.isArray(response.content)) {
      const textContent = response.content.find((item: any) => item.type === 'text');
      const toolUseContent = response.content.filter((item: any) => item.type === 'tool_use');
      
      return {
        content: textContent?.text || "",
        tool_calls: toolUseContent.map((tool: any) => ({
          id: tool.id,
          type: 'function',
          function: {
            name: tool.name,
            arguments: JSON.stringify(tool.input)
          }
        }))
      };
    }
    
    // 其他结构化格式...
    return { content: this.extractTextFromResponse(response) };
  }
  
  // 情况2：半结构化返回（需要部分解析）
  handleSemiStructuredResponse(response: any): { content: string; toolCalls?: any[] } {
    const content = this.extractTextFromResponse(response);
    
    // 尝试解析工具调用
    const toolCalls = this.parseToolCallsFromText(content);
    
    return {
      content: content,
      tool_calls: toolCalls.length > 0 ? toolCalls : undefined
    };
  }
  
  // 情况3：纯文本返回（需要完全解析）
  handleTextOnlyResponse(response: any): { content: string; toolCalls?: any[] } {
    const content = this.extractTextFromResponse(response);
    
    // 使用正则表达式或NLP技术提取工具调用
    const toolCalls = this.extractToolCallsWithNLP(content);
    
    return {
      content: content,
      tool_calls: toolCalls.length > 0 ? toolCalls : undefined
    };
  }
  
  // 从文本中解析工具调用（多种模式）
  private parseToolCallsFromText(text: string): any[] {
    const toolCalls: any[] = [];
    
    // 模式1：JSON格式
    const jsonMatches = text.match(/```json\s*(\{[\s\S]*?\})\s*```/g);
    if (jsonMatches) {
      jsonMatches.forEach(match => {
        try {
          const jsonStr = match.replace(/```json\s*|\s*```/g, '');
          const toolCall = JSON.parse(jsonStr);
          if (toolCall.tool && toolCall.arguments) {
            toolCalls.push({
              id: `call_${Date.now()}`,
              type: 'function',
              function: {
                name: toolCall.tool,
                arguments: JSON.stringify(toolCall.arguments)
              }
            });
          }
        } catch (e) {
          console.warn('Failed to parse JSON tool call:', match);
        }
      });
    }
    
    // 模式2：自然语言模式
    const functionMatches = text.match(/(?:调用|call|使用|use)\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*(?:with|参数|arguments)?\s*[:：]?\s*([^,\n]*)/g);
    if (functionMatches) {
      functionMatches.forEach(match => {
        const parts = match.split(/(?:with|参数|arguments)?\s*[:：]?\s*/);
        const toolName = parts[0].replace(/(?:调用|call|使用|use)\s+/, '').trim();
        const argsStr = parts[1]?.trim() || '{}';
        
        try {
          // 尝试解析参数
          let args = {};
          if (argsStr.startsWith('{')) {
            args = JSON.parse(argsStr);
          } else {
            // 简单键值对解析
            const keyValuePairs = argsStr.match(/(\w+)\s*[:：=]\s*([^,]+)/g);
            if (keyValuePairs) {
              keyValuePairs.forEach(pair => {
                const [key, value] = pair.split(/\s*[:：=]\s*/);
                args[key.trim()] = value.trim().replace(/^["']|["']$/g, '');
              });
            }
          }
          
          toolCalls.push({
            id: `call_${Date.now()}`,
            type: 'function',
            function: {
              name: toolName,
              arguments: JSON.stringify(args)
            }
          });
        } catch (e) {
          console.warn('Failed to parse function call:', match);
        }
      });
    }
    
    return toolCalls;
  }
  
  // 使用NLP技术提取工具调用（更高级）
  private extractToolCallsWithNLP(text: string): any[] {
    const toolCalls: any[] = [];
    
    // 简化的NLP解析示例
    const patterns = [
      // 工具名称模式
      /(?:get_weather|calculate|search|translate)\b/g,
      // 参数模式
      /(?:location|city|expression|query|text)\s*[:：=]\s*["']([^"']+)["']/g
    ];
    
    // 这里可以实现更复杂的NLP逻辑
    // 例如：使用Intent识别、实体提取等
    
    return toolCalls;
  }
  
  private extractTextFromResponse(response: any): string {
    if (response.choices?.[0]?.message?.content) {
      return response.choices[0].message.content;
    }
    if (response.choices?.[0]?.text) {
      return response.choices[0].text;
    }
    if (response.content) {
      if (typeof response.content === 'string') {
        return response.content;
      }
      if (Array.isArray(response.content)) {
        return response.content
          .filter(item => item.type === 'text')
          .map(item => item.text)
          .join('');
      }
    }
    return JSON.stringify(response);
  }
}

// 实际使用示例
export function demonstrateResponseHandling() {
  console.log(`
🔍 AI模型响应格式处理详解:

📋 1. 结构化返回（推荐）
   OpenAI GPT-4、Claude 3等现代模型支持
   直接返回 tool_calls 数组，无需解析
   
   ✅ 优点：准确、可靠、无需解析
   ❌ 缺点：需要支持function calling的模型

📋 2. 半结构化返回（兼容）
   模型在文本中包含JSON格式的工具调用
   需要正则表达式提取
   
   ✅ 优点：兼容性好
   ❌ 缺点：解析可能出错

📋 3. 纯文本返回（传统）
   模型用自然语言描述工具调用
   需要NLP技术提取
   
   ✅ 优点：适用于所有模型
   ❌ 缺点：解析复杂、准确率低

💡 实际开发建议：
   1. 优先使用支持function calling的模型
   2. 实现多级fallback机制
   3. 添加解析结果的验证
   4. 提供错误处理和重试机制
`);
}

// 改进的callLLM方法示例
export class EnhancedAgentMCPBridge extends AgentMCPBridge {
  private responseHandler = new AIAgentResponseHandler();
  
  protected async callLLM(messages: any[], tools: any[]): Promise<any> {
    console.log('Calling LLM with enhanced response handling...');
    
    // 模拟不同类型的AI响应
    const responseFormat = this.determineResponseFormat();
    const mockResponse = this.generateMockResponse(messages, tools, responseFormat);
    
    // 根据响应格式选择处理方式
    switch (responseFormat) {
      case 'structured':
        return this.responseHandler.handleStructuredResponse(mockResponse);
      case 'semi-structured':
        return this.responseHandler.handleSemiStructuredResponse(mockResponse);
      case 'text-only':
        return this.responseHandler.handleTextOnlyResponse(mockResponse);
      default:
        return this.responseHandler.handleStructuredResponse(mockResponse);
    }
  }
  
  private determineResponseFormat(): string {
    // 在实际应用中，这里会根据使用的模型决定
    const formats = ['structured', 'semi-structured', 'text-only'];
    return formats[Math.floor(Math.random() * formats.length)];
  }
  
  private generateMockResponse(messages: any[], tools: any[], format: string): any {
    const userMessage = messages.find(m => m.role === 'user')?.content || '';
    
    switch (format) {
      case 'structured':
        return {
          choices: [{
            message: {
              role: 'assistant',
              content: '我来帮您查询天气信息。',
              tool_calls: tools.length > 0 ? [{
                id: 'call_123',
                type: 'function',
                function: {
                  name: 'get_weather',
                  arguments: JSON.stringify({ location: 'Beijing' })
                }
              }] : undefined
            }
          }]
        };
        
      case 'semi-structured':
        return {
          choices: [{
            message: {
              role: 'assistant',
              content: '我来帮您查询天气信息。\n\`\`\`json\n{\n  "tool": "get_weather",\n  "arguments": {\n    "location": "Beijing"\n  }\n}\n\`\`\`'
            }
          }]
        };
        
      case 'text-only':
        return {
          choices: [{
            message: {
              role: 'assistant',
              content: '我来帮您查询天气信息。我需要调用 get_weather 工具，参数是 location: Beijing'
            }
          }]
        };
        
      default:
        return { choices: [{ message: { role: 'assistant', content: 'I understand your request.' } }] };
    }
  }
}

export { AIAgentResponseHandler, EnhancedAgentMCPBridge, demonstrateResponseHandling };

if (require.main === module) {
  demonstrateResponseHandling();
}